import axios from "axios";
import qs from "qs";
// import token from './token.js'
// let _token = token.getToken()
//     header.token = _token

import { useCommonStore, useUserStore } from "@/store";
import app from "../main";

// 同一个请求失败后最大重试次数
const MAX_RETRY_NUM = 3;
// 所有请求失败最多重试总次数
const MAX_RETRY_TOTAL_NUM = 9;
// 是否可以重试开关
const canRetry = true;
// 重试次数记录实体
const retryMap = {};
let retryTotalNum = 0;
let myHeader = {};
// 默认超时时间
const defaultTimeout = 15000;
// 话术
const timeoutMsg = "太火爆了，请稍后再试";
const errorDefaultMsg = "服务器开小差了，请稍后再试";
export default class Request {
  http(param) {
    const requestToast = app.config.globalProperties.$toast;

    // 请求参数
    let currentHeader = param.header;
    if (currentHeader) {
      for (var key in currentHeader) {
        myHeader[key] = currentHeader[key];
      }
    }
    let url = param.url,
      method = param.method || "get",
      header = myHeader,
      data = param.data || {},
      // token = param.token || "",
      dataType = param.dataType || "",
      hideLoading = param.hideLoading || false,
      thisTimeout = param.thisTimeout || defaultTimeout,
      // 禁止请求统一toast提示，交给发起请求端自行处理
      disableToast = param.disableToast;
    let requestUrl = url;

    //请求方式:GET或POST(POST需配置
    // header: {'content-type' : "application/x-www-form-urlencoded"},)
    if (method) {
      method = method.toUpperCase(); //小写改为大写
      if (method === "POST") {
        if (dataType === "json") {
          header["Content-Type"] = "application/json";
        } else if (dataType === "form") {
          header["Content-Type"] = "application/x-www-form-urlencoded";
        } else {
          header["Content-Type"] = "application/x-www-form-urlencoded";
        }
      }
    }

    //加载圈
    let useLoading = {};
    if (!hideLoading) {
      useLoading = requestToast.loading({
        message: "加载中...",
        forbidClick: true,
        loadingType: "spinner",
        overlay: true,
        duration: 0,
        overlayStyle: {
          backgroundColor: "transparent",
        },
      });
    }
    // 返回promise
    return new Promise((resolve, reject) => {
      let commonStore = useCommonStore();
      let userStore = useUserStore();
      // 请求
      console.log(data);
      let commonConfig = {
        deviceId: commonStore.deviceId,
      };
      let axiosConfig = {};
      if (method === "GET") {
        axiosConfig = {
          url: requestUrl,
          method,
          params: data,
          headers: { ...commonConfig },
        };
      } else if (method === "POST") {
        if (dataType === "json") {
          axiosConfig = {
            url: requestUrl,
            method,
            // headers: { 'content-type': 'application/json;charset=UTF-8' },
            headers: { ...commonConfig },
            data: data,
          };
        } else if (dataType === "form") {
          axiosConfig = {
            url: requestUrl,
            method,
            headers: {
              "content-type": "application/x-www-form-urlencoded;charset=UTF-8",
              ...commonConfig,
            },
            data: qs.stringify(data),
          };
        } else if (dataType === "formData") {
          // 图片信息提交需要这个headers 单独出来一个
          axiosConfig = {
            url: requestUrl,
            method,
            headers: { "content-type": "multipart/form-data", ...commonConfig },
            data: data,
          };
        } else {
          axiosConfig = {
            url: requestUrl,
            method,
            headers: {
              "content-type": "application/x-www-form-urlencoded;charset=UTF-8",
              ...commonConfig,
            },
            data: qs.stringify(data),
          };
        }
      }
      axiosConfig.timeout = thisTimeout;
      console.log("axios-Header", header);
      const requestOnce = () =>
        axios(axiosConfig)
          .then((res) => {
            if (!hideLoading) {
              useLoading.clear && useLoading.clear();
            }
            console.log("axios=========", res);
            // code判断:200成功,不等于200错误
            if (res.status && res.status != 200) {
              requestToast({
                message: errorDefaultMsg,
                duration: 2500,
              });
              return;
            }
            const { status, msg } = res.data;

            if (+status === 0) {
              // 请求成功
              // 重置retry次数
              if (canRetry && retryMap[url] && retryMap[url] > 0) {
                retryMap[url] = 0;
              }
              resolve(res.data);
              return res.data;
            } else if (+status === 202) {
              // retry once
              // 少于最高重试次数则再发一次请求
              if (
                canRetry &&
                (!retryMap[url] || retryMap[url] <= MAX_RETRY_NUM) &&
                retryTotalNum <= MAX_RETRY_TOTAL_NUM
              ) {
                retryMap[url] = (retryMap[url] || 0) + 1;
                retryTotalNum += 1;
                return requestOnce();
              }
              // return Service.logout()
            } else if (+status === 266) {
              // 用户未登录
              userStore.commit("clearStorage", "266");
              return;
            } else if (!disableToast) {
              requestToast({
                message: msg || timeoutMsg,
                duration: 2500,
              });
            }
            // 将结果抛出
            resolve(res.data);
          })
          .catch((err) => {
            if (!hideLoading) {
              useLoading.clear && useLoading.clear();
            }
            console.log("看看报啥错误了？？？", err);
            if (!disableToast && err && err.message.indexOf("timeout") > -1) {
              requestToast({
                message: timeoutMsg,
                duration: 2500,
              });
            } else if (
              !disableToast &&
              err &&
              err.message.indexOf("Network Error") > -1
            ) {
              requestToast({
                message: "前方网络拥挤，请稍后再试",
                duration: 2500,
              });
            }
            reject();
          });
      requestOnce();
    });
  }
}
